home *** CD-ROM | disk | FTP | other *** search
/ PC World 2008 February (DVD) / PCWorld_2008-02_DVD.iso / v cisle / PHP / PHP.exe / xampp-win32-1.6.5-installer.exe / phpMyAdmin / libraries / File.class.php < prev    next >
Encoding:
PHP Script  |  2007-12-20  |  25.7 KB  |  878 lines

  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4.  * file upload functions
  5.  *
  6.  * @version $Id: File.class.php 10395 2007-05-15 06:18:21Z cybot_tm $
  7.  */
  8.  
  9. /**
  10.  *
  11.  * @todo replace error messages with localized string
  12.  * @todo when uploading a file into a blob field, should we also consider using
  13.  *       chunks like in import? UPDATE `table` SET `field` = `field` + [chunk]
  14.  */
  15. class PMA_File
  16. {
  17.     /**
  18.      * @var string the temporary file name
  19.      * @access protected
  20.      */
  21.     var $_name = null;
  22.  
  23.     /**
  24.      * @var string the content
  25.      * @access protected
  26.      */
  27.     var $_content = null;
  28.  
  29.     /**
  30.      * @var string the error message
  31.      * @access protected
  32.      */
  33.     var $_error_message = '';
  34.  
  35.     /**
  36.      * @var bool whether the file is temporary or not
  37.      * @access protected
  38.      */
  39.     var $_is_temp = false;
  40.  
  41.     /**
  42.      * @var string type of compression
  43.      * @access protected
  44.      */
  45.     var $_compression = null;
  46.  
  47.     /**
  48.      * @var integer
  49.      */
  50.     var $_offset = 0;
  51.  
  52.     /**
  53.      * @var integer size of chunk to read with every step
  54.      */
  55.     var $_chunk_size = 32768;
  56.  
  57.     /**
  58.      * @var resource file handle
  59.      */
  60.     var $_handle = null;
  61.  
  62.     /**
  63.      * @var boolean whether to decompress content before returning
  64.      */
  65.     var $_decompress = false;
  66.  
  67.     /**
  68.      * @var string charset of file
  69.      */
  70.     var $_charset = null;
  71.  
  72.     /**
  73.      * old PHP 4 style constructor
  74.      *
  75.      * @see     PMA_File::__construct()
  76.      * @uses    PMA_File::__construct()
  77.      * @access  public
  78.      */
  79.     function PMA_File($name = false)
  80.     {
  81.         $this->__construct($name);
  82.     }
  83.  
  84.     /**
  85.      * constructor
  86.      *
  87.      * @access  public
  88.      * @uses    PMA_File::setName()
  89.      * @param   string  $name   file name
  90.      */
  91.     function __construct($name = false)
  92.     {
  93.         if ($name) {
  94.             $this->setName($name);
  95.         }
  96.     }
  97.  
  98.     /**
  99.      * destructor
  100.      *
  101.      * @see     PMA_File::cleanUp()
  102.      * @access  public
  103.      * @uses    PMA_File::cleanUp()
  104.      */
  105.     function __destruct()
  106.     {
  107.         $this->cleanUp();
  108.     }
  109.  
  110.     /**
  111.      * deletes file if it is temporary, usally from a moved upload file
  112.      *
  113.      * @access  public
  114.      * @uses    PMA_File::delet()
  115.      * @uses    PMA_File::isTemp()
  116.      * @return  boolean success
  117.      */
  118.     function cleanUp()
  119.     {
  120.         if ($this->isTemp()) {
  121.             return $this->delete();
  122.         }
  123.  
  124.         return true;
  125.     }
  126.  
  127.     /**
  128.      * deletes the file
  129.      *
  130.      * @access  public
  131.      * @uses    PMA_File::getName()
  132.      * @uses    unlink()
  133.      * @return  boolean success
  134.      */
  135.     function delete()
  136.     {
  137.         return unlink($this->getName());
  138.     }
  139.  
  140.     /**
  141.      * checks or sets the temp flag for this file
  142.      * file objects with temp flags are deleted with object destruction
  143.      *
  144.      * @access  public
  145.      * @uses    PMA_File::$_is_temp to set and read it
  146.      * @param   boolean sets the temp flag
  147.      * @return  boolean PMA_File::$_is_temp
  148.      */
  149.     function isTemp($is_temp = null)
  150.     {
  151.         if (null !== $is_temp) {
  152.             $this->_is_temp = (bool) $is_temp;
  153.         }
  154.  
  155.         return $this->_is_temp;
  156.     }
  157.  
  158.     /**
  159.      * accessor
  160.      *
  161.      * @access  public
  162.      * @uses    PMA_File::$_name
  163.      * @param   string  $name   file name
  164.      * @access  public
  165.      */
  166.     function setName($name)
  167.     {
  168.         $this->_name = trim($name);
  169.     }
  170.  
  171.     /**
  172.      * @access  public
  173.      * @uses    PMA_File::getName()
  174.      * @uses    PMA_File::isUploaded()
  175.      * @uses    PMA_File::checkUploadedFile()
  176.      * @uses    PMA_File::isReadable()
  177.      * @uses    PMA_File::$_content
  178.      * @uses    function_exists()
  179.      * @uses    file_get_contents()
  180.      * @uses    filesize()
  181.      * @uses    fread()
  182.      * @uses    fopen()
  183.      * @uses    bin2hex()
  184.      * @return  string  binary file content
  185.      */
  186.     function getContent($as_binary = true, $offset = 0, $length = null)
  187.     {
  188.         if (null === $this->_content) {
  189.             if ($this->isUploaded() && ! $this->checkUploadedFile()) {
  190.                 return false;
  191.             }
  192.  
  193.             if (! $this->isReadable()) {
  194.                 return false;
  195.             }
  196.  
  197.             if (function_exists('file_get_contents')) {
  198.                 $this->_content = file_get_contents($this->getName());
  199.             } elseif ($size = filesize($this->getName())) {
  200.                 $this->_content = fread(fopen($this->getName(), 'rb'), $size);
  201.             }
  202.         }
  203.  
  204.         if (! empty($this->_content) && $as_binary) {
  205.             return '0x' . bin2hex($this->_content);
  206.         }
  207.  
  208.         if (null !== $length) {
  209.             return substr($this->_content, $offset, $length);
  210.         } elseif ($offset > 0) {
  211.             return substr($this->_content, $offset);
  212.         }
  213.  
  214.         return $this->_content;
  215.     }
  216.  
  217.     /**
  218.      * @access  public
  219.      * @uses    PMA_File::getName()
  220.      * @uses    is_uploaded_file()
  221.      */
  222.     function isUploaded()
  223.     {
  224.         return is_uploaded_file($this->getName());
  225.     }
  226.  
  227.     /**
  228.      * accessor
  229.      *
  230.      * @access  public
  231.      * @uses    PMA_File::$name as return value
  232.      * @return  string  PMA_File::$_name
  233.      */
  234.     function getName()
  235.     {
  236.         return $this->_name;
  237.     }
  238.  
  239.     /**
  240.      * @todo replace error message with localized string
  241.      * @access  public
  242.      * @uses    PMA_File::isUploaded()
  243.      * @uses    PMA_File::setName()
  244.      * @uses    PMA_File::$_error_message
  245.      * @param   string  name of file uploaded
  246.      * @return  boolean success
  247.      */
  248.     function setUploadedFile($name)
  249.     {
  250.         $this->setName($name);
  251.  
  252.         if (! $this->isUploaded()) {
  253.             $this->setName(null);
  254.             $this->_error_message = 'not an uploaded file';
  255.             return false;
  256.         }
  257.  
  258.         return true;
  259.     }
  260.  
  261.     /**
  262.      * @access  public
  263.      * @uses    PMA_File::fetchUploadedFromTblChangeRequestMultiple()
  264.      * @uses    PMA_File::setUploadedFile()
  265.      * @uses    PMA_File::$_error_message
  266.      * @uses    $GLOBALS['strUploadErrorIniSize']
  267.      * @uses    $GLOBALS['strUploadErrorFormSize']
  268.      * @uses    $GLOBALS['strUploadErrorPartial']
  269.      * @uses    $GLOBALS['strUploadErrorNoTempDir']
  270.      * @uses    $GLOBALS['strUploadErrorCantWrite']
  271.      * @uses    $GLOBALS['strUploadErrorExtension']
  272.      * @uses    $GLOBALS['strUploadErrorUnknown']
  273.      * @uses    $_FILES
  274.      * @param   string  $key    a numeric key used to identify the different rows
  275.      * @param   string  $primary_key
  276.      * @return  boolean success
  277.      */
  278.     function setUploadedFromTblChangeRequest($key, $primary = null)
  279.     {
  280.         if (! isset($_FILES['fields_upload_' . $key])) {
  281.             return false;
  282.         }
  283.  
  284.         $file = $_FILES['fields_upload_' . $key];
  285.         if (null !== $primary) {
  286.             $file = PMA_File::fetchUploadedFromTblChangeRequestMultiple($file, $primary);
  287.         }
  288.  
  289.         // check for file upload errors
  290.         switch ($file['error']) {
  291.             // cybot_tm: we do not use the PHP constants here cause not all constants
  292.             // are defined in all versions of PHP - but the correct constants names
  293.             // are given as comment
  294.             case 0: //UPLOAD_ERR_OK:
  295.                 return $this->setUploadedFile($file['tmp_name']);
  296.                 break;
  297.             case 4: //UPLOAD_ERR_NO_FILE:
  298.                 break;
  299.             case 1: //UPLOAD_ERR_INI_SIZE:
  300.                 $this->_error_message = $GLOBALS['strUploadErrorIniSize'];
  301.                 break;
  302.             case 2: //UPLOAD_ERR_FORM_SIZE:
  303.                 $this->_error_message = $GLOBALS['strUploadErrorFormSize'];
  304.                 break;
  305.             case 3: //UPLOAD_ERR_PARTIAL:
  306.                 $this->_error_message = $GLOBALS['strUploadErrorPartial'];
  307.                 break;
  308.             case 6: //UPLOAD_ERR_NO_TMP_DIR:
  309.                 $this->_error_message = $GLOBALS['strUploadErrorNoTempDir'];
  310.                 break;
  311.             case 7: //UPLOAD_ERR_CANT_WRITE:
  312.                 $this->_error_message = $GLOBALS['strUploadErrorCantWrite'];
  313.                 break;
  314.             case 8: //UPLOAD_ERR_EXTENSION:
  315.                 $this->_error_message = $GLOBALS['strUploadErrorExtension'];
  316.                 break;
  317.             default:
  318.                 $this->_error_message = $GLOBALS['strUploadErrorUnknown'];
  319.         } // end switch
  320.  
  321.         return false;
  322.     }
  323.  
  324.     /**
  325.      * strips some dimension from the multi-dimensional array from $_FILES
  326.      *
  327.      * <code>
  328.      * $file['name']['multi_edit'][$primary] = [value]
  329.      * $file['type']['multi_edit'][$primary] = [value]
  330.      * $file['size']['multi_edit'][$primary] = [value]
  331.      * $file['tmp_name']['multi_edit'][$primary] = [value]
  332.      * $file['error']['multi_edit'][$primary] = [value]
  333.      *
  334.      * // becomes:
  335.      *
  336.      * $file['name'] = [value]
  337.      * $file['type'] = [value]
  338.      * $file['size'] = [value]
  339.      * $file['tmp_name'] = [value]
  340.      * $file['error'] = [value]
  341.      * </code>
  342.      *
  343.      * @todo re-check if requirements changes to PHP >= 4.2.0
  344.      * @access  public
  345.      * @static
  346.      * @param   array   $file       the array
  347.      * @param   string  $primary
  348.      * @return  array
  349.      */
  350.     function fetchUploadedFromTblChangeRequestMultiple($file, $primary)
  351.     {
  352.         $new_file = array(
  353.             'name' => $file['name']['multi_edit'][$primary],
  354.             'type' => $file['type']['multi_edit'][$primary],
  355.             'size' => $file['size']['multi_edit'][$primary],
  356.             'tmp_name' => $file['tmp_name']['multi_edit'][$primary],
  357.             //'error' => $file['error']['multi_edit'][$primary],
  358.         );
  359.  
  360.         // ['error'] exists since PHP 4.2.0
  361.         if (isset($file['error'])) {
  362.             $new_file['error'] = $file['error']['multi_edit'][$primary];
  363.         }
  364.  
  365.         return $new_file;
  366.     }
  367.  
  368.     /**
  369.      * sets the name if the file to the one selected in the tbl_change form
  370.      *
  371.      * @access  public
  372.      * @uses    $_REQUEST
  373.      * @uses    PMA_File::setLocalSelectedFile()
  374.      * @uses    is_string()
  375.      * @param   string  $key    a numeric key used to identify the different rows
  376.      * @param   string  $primary_key
  377.      * @return  boolean success
  378.      */
  379.     function setSelectedFromTblChangeRequest($key, $primary = null)
  380.     {
  381.         if (null !== $primary) {
  382.             if (! empty($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary])
  383.              && is_string($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary])) {
  384.                 // ... whether with multiple rows ...
  385.                 return $this->setLocalSelectedFile($_REQUEST['fields_uploadlocal_' . $key]['multi_edit'][$primary]);
  386.             } else {
  387.                 return false;
  388.             }
  389.         } elseif (! empty($_REQUEST['fields_uploadlocal_' . $key])
  390.          && is_string($_REQUEST['fields_uploadlocal_' . $key])) {
  391.             return $this->setLocalSelectedFile($_REQUEST['fields_uploadlocal_' . $key]);
  392.         }
  393.  
  394.          return false;
  395.     }
  396.  
  397.     /**
  398.      * @access  public
  399.      * @uses    PMA_File->$_error_message as return value
  400.      * @return  string  error message
  401.      */
  402.     function getError()
  403.     {
  404.         return $this->_error_message;
  405.     }
  406.  
  407.     /**
  408.      * @access  public
  409.      * @uses    PMA_File->$_error_message to check it
  410.      * @return  boolean whether an error occured or not
  411.      */
  412.     function isError()
  413.     {
  414.         return ! empty($this->_error_message);
  415.     }
  416.  
  417.     /**
  418.      * checks the superglobals provided if the tbl_change form is submitted
  419.      * and uses the submitted/selected file
  420.      *
  421.      * @access  public
  422.      * @uses    PMA_File::setUploadedFromTblChangeRequest()
  423.      * @uses    PMA_File::setSelectedFromTblChangeRequest()
  424.      * @param   string  $key    a numeric key used to identify the different rows
  425.      * @param   string  $primary_key
  426.      * @return  boolean success
  427.      */
  428.     function checkTblChangeForm($key, $primary_key)
  429.     {
  430.         if ($this->setUploadedFromTblChangeRequest($key, $primary_key)) {
  431.             // well done ...
  432.             $this->_error_message = '';
  433.             return true;
  434. /*
  435.         } elseif ($this->setUploadedFromTblChangeRequest($key)) {
  436.             // well done ...
  437.             $this->_error_message = '';
  438.             return true;
  439. */
  440.         } elseif ($this->setSelectedFromTblChangeRequest($key, $primary_key)) {
  441.             // well done ...
  442.             $this->_error_message = '';
  443.             return true;
  444. /*
  445.         } elseif ($this->setSelectedFromTblChangeRequest($key)) {
  446.             // well done ...
  447.             $this->_error_message = '';
  448.             return true;
  449. */
  450.         }
  451.         // all failed, whether just no file uploaded/selected or an error
  452.  
  453.         return false;
  454.     }
  455.  
  456.     /**
  457.      *
  458.      * @access  public
  459.      * @uses    $GLOBALS['strFileCouldNotBeRead']
  460.      * @uses    PMA_File::setName()
  461.      * @uses    PMA_securePath()
  462.      * @uses    PMA_userDir()
  463.      * @uses    $GLOBALS['cfg']['UploadDir']
  464.      * @param   string  $name
  465.      * @return  boolean success
  466.      */
  467.     function setLocalSelectedFile($name)
  468.     {
  469.         $this->setName(PMA_userDir($GLOBALS['cfg']['UploadDir']) . PMA_securePath($name));
  470.         if (! $this->isReadable()) {
  471.             $this->_error_message = $GLOBALS['strFileCouldNotBeRead'];
  472.             $this->setName(null);
  473.             return false;
  474.         }
  475.  
  476.         return true;
  477.     }
  478.  
  479.     /**
  480.      * @access  public
  481.      * @uses    PMA_File::getName()
  482.      * @uses    is_readable()
  483.      * @uses    ob_start()
  484.      * @uses    ob_end_clean()
  485.      * @return  boolean whether the file is readable or not
  486.      */
  487.     function isReadable()
  488.     {
  489.         // surpress warnings from beeing displayed, but not from beeing logged
  490.         // any file access outside of open_basedir will issue a warning
  491.         ob_start();
  492.         $is_readable = is_readable($this->getName());
  493.         ob_end_clean();
  494.         return $is_readable;
  495.     }
  496.  
  497.     /**
  498.      * If we are on a server with open_basedir, we must move the file
  499.      * before opening it. The FAQ 1.11 explains how to create the "./tmp"
  500.      * directory - if needed
  501.      *
  502.      * @todo replace error message with localized string
  503.      * @todo move check of $cfg['TempDir'] into PMA_Config?
  504.      * @access  public
  505.      * @uses    $cfg['TempDir']
  506.      * @uses    $GLOBALS['strFieldInsertFromFileTempDirNotExists']
  507.      * @uses    PMA_File::isReadable()
  508.      * @uses    PMA_File::getName()
  509.      * @uses    PMA_File::setName()
  510.      * @uses    PMA_File::isTemp()
  511.      * @uses    PMA_File::$_error_message
  512.      * @uses    is_dir()
  513.      * @uses    mkdir()
  514.      * @uses    chmod()
  515.      * @uses    is_writable()
  516.      * @uses    basename()
  517.      * @uses    move_uploaded_file()
  518.      * @uses    ob_start()
  519.      * @uses    ob_end_clean()
  520.      * @return  boolean whether uploaded fiel is fine or not
  521.      */
  522.     function checkUploadedFile()
  523.     {
  524.         if ($this->isReadable()) {
  525.             return true;
  526.         }
  527.  
  528.         /**
  529.          * it is not important if open_basedir is set - we just cannot read the file
  530.          * so we try to move it
  531.         if ('' != ini_get('open_basedir')) {
  532.          */
  533.  
  534.         // check tmp dir config
  535.         if (empty($GLOBALS['cfg']['TempDir'])) {
  536.             $GLOBALS['cfg']['TempDir'] = 'tmp/';
  537.         }
  538.  
  539.         // surpress warnings from beeing displayed, but not from beeing logged
  540.         ob_start();
  541.         // check tmp dir
  542.         if (! is_dir($GLOBALS['cfg']['TempDir'])) {
  543.             // try to create the tmp directory
  544.             if (@mkdir($GLOBALS['cfg']['TempDir'], 0777)) {
  545.                 chmod($GLOBALS['cfg']['TempDir'], 0777);
  546.             } else {
  547.                 // create tmp dir failed
  548.                 $this->_error_message = $GLOBALS['strFieldInsertFromFileTempDirNotExists'];
  549.                 ob_end_clean();
  550.                 return false;
  551.             }
  552.         }
  553.         ob_end_clean();
  554.  
  555.         if (! is_writable($GLOBALS['cfg']['TempDir'])) {
  556.             // cannot create directory or access, point user to FAQ 1.11
  557.             $this->_error_message = $GLOBALS['strFieldInsertFromFileTempDirNotExists'];
  558.             return false;
  559.         }
  560.  
  561.         $new_file_to_upload = $GLOBALS['cfg']['TempDir'] . '/' . basename($this->getName());
  562.  
  563.         // surpress warnings from beeing displayed, but not from beeing logged
  564.         // any file access outside of open_basedir will issue a warning
  565.         ob_start();
  566.         $move_uploaded_file_result = move_uploaded_file($this->getName(), $new_file_to_upload);
  567.         ob_end_clean();
  568.         if (! $move_uploaded_file_result) {
  569.             $this->_error_message = 'error while moving uploaded file';
  570.             return false;
  571.         }
  572.  
  573.         $this->setName($new_file_to_upload);
  574.         $this->isTemp(true);
  575.  
  576.         if (! $this->isReadable()) {
  577.             $this->_error_message = 'cannot read (moved) upload file';
  578.             return false;
  579.         }
  580.  
  581.         return true;
  582.     }
  583.  
  584.     /**
  585.      * Detects what compression filse uses
  586.      *
  587.      * @todo    move file read part into readChunk() or getChunk()
  588.      * @todo    add support for compression plugins
  589.      * @uses    $GLOBALS['strFileCouldNotBeRead']
  590.      * @uses    PMA_File::$_compression to set it
  591.      * @uses    PMA_File::getName()
  592.      * @uses    fopen()
  593.      * @uses    fread()
  594.      * @uses    strlen()
  595.      * @uses    fclose()
  596.      * @uses    chr()
  597.      * @uses    substr()
  598.      * @access  protected
  599.      * @return  string MIME type of compression, none for none
  600.      */
  601.     function _detectCompression()
  602.     {
  603.         // surpress warnings from beeing displayed, but not from beeing logged
  604.         // f.e. any file access outside of open_basedir will issue a warning
  605.         ob_start();
  606.         $file = fopen($this->getName(), 'rb');
  607.         ob_end_clean();
  608.  
  609.         if (! $file) {
  610.             $this->_error_message = $GLOBALS['strFileCouldNotBeRead'];
  611.             return false;
  612.         }
  613.  
  614.         /**
  615.          * @todo
  616.          * get registered plugins for file compression
  617.  
  618.         foreach (PMA_getPlugins($type = 'compression') as $plugin) {
  619.             if (call_user_func_array(array($plugin['classname'], 'canHandle'), array($this->getName()))) {
  620.                 $this->setCompressionPlugin($plugin);
  621.                 break;
  622.             }
  623.         }
  624.          */
  625.  
  626.         $test = fread($file, 4);
  627.         $len = strlen($test);
  628.         fclose($file);
  629.  
  630.         if ($len >= 2 && $test[0] == chr(31) && $test[1] == chr(139)) {
  631.             $this->_compression = 'application/gzip';
  632.         } elseif ($len >= 3 && substr($test, 0, 3) == 'BZh') {
  633.             $this->_compression = 'application/bzip2';
  634.         } elseif ($len >= 4 && $test == "PK\003\004") {
  635.             $this->_compression = 'application/zip';
  636.         } else {
  637.             $this->_compression = 'none';
  638.         }
  639.  
  640.         return $this->_compression;
  641.     }
  642.  
  643.     /**
  644.      * whether the content should be decompressed before returned
  645.      */
  646.     function setDecompressContent($decompress)
  647.     {
  648.         $this->_decompress = (bool) $decompress;
  649.     }
  650.  
  651.     function getHandle()
  652.     {
  653.         if (null === $this->_handle) {
  654.             $this->open();
  655.         }
  656.         return $this->_handle;
  657.     }
  658.  
  659.     function setHandle($handle)
  660.     {
  661.         $this->_handle = $handle;
  662.     }
  663.  
  664.     /**
  665.      *
  666.      */
  667.     function open()
  668.     {
  669.         if (! $this->_decompress) {
  670.             $this->_handle = @fopen($this->getName(), 'r');
  671.         }
  672.  
  673.         switch ($this->getCompression()) {
  674.             case false:
  675.                 return false;
  676.             case 'application/bzip2':
  677.                 if ($GLOBALS['cfg']['BZipDump'] && @function_exists('bzopen')) {
  678.                     $this->_handle = @bzopen($this->getName(), 'r');
  679.                 } else {
  680.                     $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  681.                     return false;
  682.                 }
  683.                 break;
  684.             case 'application/gzip':
  685.                 if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzopen')) {
  686.                     $this->_handle = @gzopen($this->getName(), 'r');
  687.                 } else {
  688.                     $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  689.                     return false;
  690.                 }
  691.                 break;
  692.             case 'application/zip':
  693.                 if ($GLOBALS['cfg']['GZipDump'] && @function_exists('gzinflate')) {
  694.                     include_once './libraries/unzip.lib.php';
  695.                     $this->_handle = new SimpleUnzip();
  696.                     $this->_handle->ReadFile($this->getName());
  697.                     if ($this->_handle->Count() == 0) {
  698.                         $this->_error_message = $GLOBALS['strNoFilesFoundInZip'];
  699.                         return false;
  700.                     } elseif ($this->_handle->GetError(0) != 0) {
  701.                         $this->_error_message = $GLOBALS['strErrorInZipFile'] . ' ' . $this->_handle->GetErrorMsg(0);
  702.                         return false;
  703.                     } else {
  704.                         $this->content_uncompressed = $this->_handle->GetData(0);
  705.                     }
  706.                     // We don't need to store it further
  707.                     $this->_handle = null;
  708.                 } else {
  709.                     $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  710.                     return false;
  711.                 }
  712.                 break;
  713.             case 'none':
  714.                 $this->_handle = @fopen($this->getName(), 'r');
  715.                 break;
  716.             default:
  717.                 $this->_error_message = sprintf($GLOBALS['strUnsupportedCompressionDetected'], $this->getCompression());
  718.                 return false;
  719.                 break;
  720.         }
  721.  
  722.  
  723.     }
  724.  
  725.     function getCharset()
  726.     {
  727.         return $this->_charset;
  728.     }
  729.  
  730.     function setCharset($charset)
  731.     {
  732.         $this->_charset = $charset;
  733.     }
  734.  
  735.     /**
  736.      * @uses    PMA_File::$_compression as return value
  737.      * @uses    PMA_File::detectCompression()
  738.      * @return  string MIME type of compression, none for none
  739.      * @access  public
  740.      */
  741.     function getCompression()
  742.     {
  743.         if (null === $this->_compression) {
  744.             return $this->_detectCompression();
  745.         }
  746.  
  747.         return $this->_compression;
  748.     }
  749.  
  750.     /**
  751.      * advances the file pointer in the file handle by $length bytes/chars
  752.      *
  753.      * @param   integer $length numbers of chars/bytes to skip
  754.      * @return  boolean
  755.      */
  756.     function advanceFilePointer($length)
  757.     {
  758.         while ($length > 0) {
  759.             // Disable read progresivity, otherwise we eat all memory!
  760.             $read_multiply = 1; // required?
  761.             $this->getNextChunk($length);
  762.             $length -= $this->getChunkSize();
  763.         }
  764.     }
  765.  
  766.     /**
  767.      * http://bugs.php.net/bug.php?id=29532
  768.      * bzip reads a maximum of 8192 bytes on windows systems
  769.      *
  770.      */
  771.     function getNextChunk($max_size = null)
  772.     {
  773.         if (null !== $max_size) {
  774.             $size = min($max_size, $this->getChunkSize());
  775.         } else {
  776.             $size = $this->getChunkSize();
  777.         }
  778.  
  779.         // $result = $this->handler->getNextChunk($size);
  780.         $result = '';
  781.         switch ($this->getCompression()) {
  782.             case 'application/bzip2':
  783.                 $result = '';
  784.                 while (strlen($result) < $size - 8192 && ! feof($this->getHandle())) {
  785.                     $result .= bzread($this->getHandle(), $size);
  786.                 }
  787.                 break;
  788.             case 'application/gzip':
  789.                 $result = gzread($this->getHandle(), $size);
  790.                 break;
  791.             case 'application/zip':
  792.                 include_once './libraries/unzip.lib.php';
  793.                 $import_handle = new SimpleUnzip();
  794.                 $import_handle->ReadFile($this->getName());
  795.                 if ($import_handle->Count() == 0) {
  796.                     $this->_error_message = $GLOBALS['strNoFilesFoundInZip'];
  797.                     return false;
  798.                 } elseif ($import_handle->GetError(0) != 0) {
  799.                     $this->_error_message = $GLOBALS['strErrorInZipFile']
  800.                         . ' ' . $import_handle->GetErrorMsg(0);
  801.                     return false;
  802.                 } else {
  803.                     $result = $import_handle->GetData(0);
  804.                 }
  805.                 break;
  806.             case 'none':
  807.                 $result = fread($this->getHandle(), $size);
  808.                 break;
  809.             default:
  810.                 return false;
  811.         }
  812.  
  813.         echo $size . ' - ';
  814.         echo strlen($result) . ' - ';
  815.         echo (@$GLOBALS['__len__'] += strlen($result)) . ' - ';
  816.         echo $this->_error_message;
  817.         echo '<hr />';
  818.  
  819.         if ($GLOBALS['charset_conversion']) {
  820.             $result = PMA_convert_string($this->getCharset(), $GLOBALS['charset'], $result);
  821.         } else {
  822.             /**
  823.              * Skip possible byte order marks (I do not think we need more
  824.              * charsets, but feel free to add more, you can use wikipedia for
  825.              * reference: <http://en.wikipedia.org/wiki/Byte_Order_Mark>)
  826.              *
  827.              * @todo BOM could be used for charset autodetection
  828.              */
  829.             if ($this->getOffset() === 0) {
  830.                 // UTF-8
  831.                 if (strncmp($result, "\xEF\xBB\xBF", 3) == 0) {
  832.                     $result = substr($result, 3);
  833.                 // UTF-16 BE, LE
  834.                 } elseif (strncmp($result, "\xFE\xFF", 2) == 0
  835.                  || strncmp($result, "\xFF\xFE", 2) == 0) {
  836.                     $result = substr($result, 2);
  837.                 }
  838.             }
  839.         }
  840.  
  841.         $this->_offset += $size;
  842.         if (0 === $result) {
  843.             return true;
  844.         }
  845.         return $result;
  846.     }
  847.  
  848.     function getOffset()
  849.     {
  850.         return $this->_offset;
  851.     }
  852.  
  853.     function getChunkSize()
  854.     {
  855.         return $this->_chunk_size;
  856.     }
  857.  
  858.     function setChunkSize($chunk_size)
  859.     {
  860.         $this->_chunk_size = (int) $chunk_size;
  861.     }
  862.  
  863.     function getContentLength()
  864.     {
  865.         return strlen($this->_content);
  866.     }
  867.  
  868.     function eof()
  869.     {
  870.         if ($this->getHandle()) {
  871.             return feof($this->getHandle());
  872.         } else {
  873.             return ($this->getOffset() >= $this->getContentLength());
  874.         }
  875.  
  876.     }
  877. }
  878. ?>